package com.huixuebao.after.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Predicates;
import com.huixuebao.after.dto.ClassFunctionDTO;
import com.huixuebao.after.dto.FunctionDTO;
import com.huixuebao.after.dto.UserFunctionDTO;
import com.huixuebao.after.entity.FunctionEntity;
import com.huixuebao.after.entity.UserEntity;
import com.huixuebao.after.mapper.FunctionMapper;
import com.huixuebao.after.mapper.UserMapper;
import com.huixuebao.after.service.FunctionService;
import com.huixuebao.common.bean.ApiResult;
import com.huixuebao.common.enumeration.ResultCodeEnum;
import com.huixuebao.common.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FunctionServiceImpl implements FunctionService {

    @Autowired
    private FunctionMapper functionMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public ApiResult<List<ClassFunctionDTO>> getFunctionTree(HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String userType = JWTUtils.getUserType(request);
            if ("0".equals(userType)) {
                List<FunctionDTO> functionDto = listDTO("10000001","0");
                for (FunctionDTO dto : functionDto) {
                    getChilds(dto,"0");
                }
                List<FunctionDTO> functionDto1 = listDTO("10000001","1");
                for (FunctionDTO dto : functionDto1) {
                    getChilds(dto,"1");
                }
                ClassFunctionDTO  cfd = new ClassFunctionDTO();
                cfd.setAdmin(functionDto);
                cfd.setMechanism(functionDto1);
                apiResult.setData(cfd);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取树状结构成功！！");
            }else {
                List<FunctionDTO> functionDto = listDTO("10000001","1");
                for (FunctionDTO dto : functionDto) {
                    getChilds(dto,"1");
                }
                ClassFunctionDTO cfd= new ClassFunctionDTO();
                cfd.setMechanism(functionDto);
                apiResult.setData(cfd);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取树状结构成功！！");
            }
        }catch (Exception e) {
            log.info("菜单树获取失败");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取菜单树失败！！");
        }
        return apiResult;
    }

    @Override
    public ApiResult getUserFunction(HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String userId = JWTUtils.getUserId(request);
            if (StrUtil.isEmpty(userId)){
                apiResult.setSuccess(false);
                //如果userId为空返回前端为3333
                apiResult.setCode(ResultCodeEnum.ERROR_TOKENTIMEERROR.getCode());
                apiResult.setMessage("请登陆!!,为查询到当前账号!!!");
                return apiResult;
            }else {
                UserEntity id = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId,userId));
                List<FunctionDTO> functionEntityList = functionMapper.selectFunctionList(userId);
                List<FunctionDTO> oneList = functionEntityList.stream().filter(l->l.getFunType().equals(0)).sorted((a,b)->a.getSort().compareTo(b.getSort())).collect(Collectors.toList());
                List<FunctionDTO> twoList = functionEntityList.stream().filter(l->l.getFunType()==1).collect(Collectors.toList());
                List<FunctionDTO> threeList = functionEntityList.stream().filter(l->l.getFunType()==2).collect(Collectors.toList());
                for (FunctionDTO dto: oneList) {
                    List<FunctionDTO> tempTwoList = twoList.stream().filter(l->l.getPid().equals(dto.getId())).collect(Collectors.toList());
                    List<FunctionDTO> resultTwoList = tempTwoList.stream().map(tempTwo ->{
                        List<FunctionDTO> threeTempList = threeList.stream().filter(l->l.getPid().equals(tempTwo.getId())).collect(Collectors.toList());
                        threeTempList.sort((a,b)->a.getSort().compareTo(b.getSort()));
                        tempTwo.setChildren(threeTempList);
                        return tempTwo;
                    }).collect(Collectors.toList());
                    resultTwoList.sort((a,b)->a.getSort().compareTo(b.getSort()));
                    dto.setChildren(resultTwoList);
                }
                for (FunctionDTO dto: oneList) {
                    if(dto.getChildren().size()==0){
                        List<FunctionDTO> tempList = threeList.stream().filter(l->l.getPid().equals(dto.getId())).collect(Collectors.toList());
                        dto.setChildren(tempList);
                    }
                }
                UserFunctionDTO userFunctionDTO = new UserFunctionDTO();
                userFunctionDTO.setUserName(id.getUserName());
                userFunctionDTO.setMechanismId(id.getMechanismId());
                userFunctionDTO.setUserType(id.getUserType());
                userFunctionDTO.setData(oneList);
                apiResult.setData(userFunctionDTO);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取用户菜单信息成功!!");
                return apiResult;
            }
        }catch (Exception e){
            log.info("获取用户菜单失败!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取用户菜单失败!!");
        }
        return apiResult;
    }

    /**
     * 获取菜单树信息，单棵树结构
     * @param request
     * @return
     */
    @Override
    public ApiResult<List<FunctionDTO>> getSingTree(HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try{
            String userType = JWTUtils.getUserType(request);
            if ("0".equals(userType)){
                List<FunctionDTO> functionDTOS = listDTO("10000001","");
                for(FunctionDTO dto: functionDTOS){
                    getChilds(dto,userType);
                }
                ClassFunctionDTO cfd= new ClassFunctionDTO();
                cfd.setMechanism(functionDTOS);
                apiResult.setData(cfd);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取单树机构信息成功！！");
            }
        }catch (Exception e){
            log.info("菜单树获取失败");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取菜单树失败！！");
        }
        return apiResult;
    }

    /**
     * 添加菜单信息
     * @param functionDTO
     * @return
     */
    @Override
    public ApiResult addFunction(FunctionDTO functionDTO) {
        ApiResult apiResult = new ApiResult();
        try {
            String pid = functionDTO.getPid();
            String functionName = functionDTO.getFunName();
            Integer funType =Integer.valueOf(functionDTO.getFunType());
            String url = functionDTO.getFunUrl();
            String icon = functionDTO.getFunIcon();
            Integer sort = Integer.valueOf(functionDTO.getSort());
            String status = functionDTO.getStatus();
            String userType = functionDTO.getUserType();
            String remark = functionDTO.getRemark();
            if(StrUtil.isNotEmpty(functionName) && StrUtil.isNotEmpty(userType) && ObjectUtil.isNotNull(sort) && ObjectUtil.isNotNull(funType)){
                FunctionEntity functionEntity = new FunctionEntity();
                functionEntity.setPid(pid);
                functionEntity.setFunName(functionName);
                functionEntity.setFunType(funType);
                functionEntity.setFunUrl(url);
                functionEntity.setFunIcon(icon);
                functionEntity.setSort(sort);
                functionEntity.setStatus(status);
                functionEntity.setRemark(remark);
                functionEntity.setCreateTime(new DateTime());
                functionEntity.setUserType(userType);
                functionEntity.setId(IdUtil.fastSimpleUUID());
                functionMapper.insert(functionEntity);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("添加菜单信息成功");
            }else {
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("必填字段不能为空!!");
            }
        }catch (Exception e){
            log.info("必填字段不能为空!!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("添加菜单信息失败！！");
        }
        return apiResult;
    }

    @Override
    public ApiResult editFunction(FunctionDTO functionDTO) {
        ApiResult apiResult = new ApiResult();
        try {
            String pid = functionDTO.getPid();
            String id = functionDTO.getId();
            String status = functionDTO.getStatus();
            String functionName = functionDTO.getFunName();
            Integer funType =Integer.valueOf(functionDTO.getFunType());
            String url = functionDTO.getFunUrl();
            String icon = functionDTO.getFunIcon();
            Integer sort = Integer.valueOf(functionDTO.getSort());
            String userType = functionDTO.getUserType();
            String remark = functionDTO.getRemark();
            if(StrUtil.isNotEmpty(functionName) && ObjectUtil.isNotNull(sort) && ObjectUtil.isNotNull(funType)){
                FunctionEntity functionId = functionMapper.selectById(id);
                functionId.setFunName(functionName);
                functionId.setPid(pid);
                functionId.setFunType(funType);
                functionId.setFunUrl(url);
                functionId.setFunIcon(icon);
                functionId.setSort(sort);
                functionId.setStatus(status);
                functionId.setRemark(remark);
                functionId.setUserType(userType);
                functionId.setUpdateTime(new DateTime());
                functionMapper.updateById(functionId);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("编辑菜单信息成功");
            }else {
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("必填字段不能为空!!");
            }
        }catch (Exception e){
            log.info("编辑菜单信息异常");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("编辑菜单信息失败!!" + e.getMessage());
        }
        return apiResult;
    }

    @Override
    public ApiResult deleteFunction(FunctionDTO functionDTO) {
        ApiResult apiResult = new ApiResult();
        try{
            String id = functionDTO.getId();
            if(StrUtil.isNotEmpty(id)){
                FunctionEntity functionId = functionMapper.selectOne(new LambdaQueryWrapper<FunctionEntity>().eq(FunctionEntity::getId,id));
                String funId = functionId.getId();
                functionMapper.deleteById(funId);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("删除菜单信息成功!!");
            }else {
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("没有获取菜单id!!");
            }
        }catch (Exception e){
            log.info("删除菜单信息异常!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("删除菜单信息失败!!");
        }
        return apiResult;
    }


    private List<FunctionDTO> listDTO(String pid,String userType){
        List<FunctionEntity> list = functionMapper.selectList(new LambdaQueryWrapper<FunctionEntity>().eq(FunctionEntity::getPid,pid));
        Predicate<FunctionEntity> p2 = (n)-> n.getUserType().contains("1");

        if("1".equals(userType)){
            list = list.stream().filter(p2).collect(Collectors.toList());
        }
        List<FunctionDTO> result = new ArrayList<>();
        list.forEach(entity -> {
            FunctionDTO dto = new FunctionDTO();
            BeanUtil.copyProperties(entity,dto);
            result.add(dto);
        });
        return result;
    }

    private void getChilds(FunctionDTO functionDTO,String userType){

            List<FunctionDTO> childs = listDTO(functionDTO.getId(),userType);
            functionDTO.setChildren(childs);
            for (FunctionDTO childFunction: childs){
                getChilds(childFunction,userType);
            }
    }

}
